/* 
 * libsaxychord
 *
 * Choi Jonghwan<saxboy@saxboy.pe.kr>
 * 2005/02/19
 *
 * - Written in KLDP CodeFest :-)
 */

#ifndef __NOTE_H__
#define __NOTE_H__

/* note definitions 
 *
 * these note definitions are modelled after the midi notes in mind
 * so we need octave, absolute note should be computed from the octave.
 */
enum __notes {
	NOTE_C=0, 
	NOTE_C_SHARP=1, NOTE_D_FLAT=1, 
	NOTE_D=2, 
	NOTE_D_SHARP=3, NOTE_E_FLAT=3, 
	NOTE_E=4, 
	NOTE_E_SHARP=5,  /* same as F, actually needless */
	NOTE_F_FLAT=4,  /* same as E, actually needless */
	NOTE_F=5, 
	NOTE_F_SHARP=6, NOTE_G_FLAT=6, 
	NOTE_G=7, 
	NOTE_G_SHARP=8, NOTE_A_FLAT=8, 
	NOTE_A=9, 
	NOTE_A_SHARP=10, NOTE_B_FLAT=10, 
	NOTE_B=11, 
	NOTE_B_SHARP=10, /* same as C, actually needless */
	NOTE_C_FLAT=10 /* same as B, actually needless */
}; 

/* interval definitions */
enum __interval 
{
	INTERVAL_MINOR_SECOND=1, 
	INTERVAL_MAJOR_SECOND=2, 
	INTERVAL_MINOR_THIRD=3, 
	INTERVAL_MAJOR_THIRD=4, 
	INTERVAL_PERFECT_FOURTH=5, 
	INTERVAL_AUGMENTED_FOURTH=6, 
	INTERVAL_DIMINISHED_FIFTH=6, /* same as aug fourth */
	INTERVAL_PERFECT_FIFTH=7, 
	INTERVAL_AUGMENTED_FIFTH=8, 
	INTERVAL_MINOR_SIXTH=9, 
	INTERVAL_MINOR_SEVENTH=10, 
	INTERVAL_MAJOR_SEVENTH=11, 

	/* some meta defs */
	INTERVAL_MINOR=100, 
	INTERVAL_MAJOR=101, 
	INTERVAL_PERFECT=102, 
	INTERVAL_DIMINISHED=103, 
	INTERVAL_AUGMENTED=104, 

}; 

/* note name flavors */
enum __note_flavor
{
	NOTE_FLAVOR_DONTCARE=0, 
	NOTE_FLAVOR_SHARP, 
	NOTE_FLAVOR_FLAT, 
}; 

/* note lengths 
 * see http://en.wikipedia.org/wiki/Note_value for details
 *
 * L.S.M of 2, 3, 5, 64 = 960, to support tuplets
 *
 * FIXME: recalc length... :-<
 */
typedef enum __note_length
{
	NOTE_WHOLE=1280, 
	NOTE_DOUBLE_DOTTED_HALF=1120, 
	NOTE_DOTTED_HALF=960, 
	NOTE_HALF=640, 
	NOTE_DOUBLE_DOTTED_QUARTER=560, 
	//NOTE_TRIPLET_QUARTER=480, 
	NOTE_DOTTED_QUARTER=480, 
	NOTE_QUARTER=320, 
	NOTE_DOUBLE_DOTTED_EIGHTH=280, 
	NOTE_DOTTED_EIGHTH=240, 
	NOTE_EIGHTH=160, 
	NOTE_DOUBLE_DOTTED_SIXTEENTH=140, 
	NOTE_DOTTED_SIXTEENTH=120, 
	NOTE_SIXTEENTH=80, 
	NOTE_DOUBLE_DOTTED_THIRTYSECOND=70, /* we actually don't have that */
	NOTE_DOTTED_THIRTYSECOND=60, 
	NOTE_THIRTYSECOND=40, 
	NOTE_SIXTYFOUTH=20, 

} NOTE_LENGTH; 

typedef struct __NOTE {
	int abs_note; 

//	int rel_note; 
//	int octave; 

	int length; 

} _NOTE; 
typedef _NOTE *NOTE; 

/* public note API's */

NOTE note_New(void);
NOTE note_NewFromString(const char *notestr);
NOTE note_Copy(NOTE n); 
int note_Delete(NOTE n);
int note_SetLength(NOTE n, NOTE_LENGTH l); 
int note_GetLength(NOTE n); 
int note_RaiseHalf(NOTE n);
int note_LowerHalf(NOTE n);
int note_RaiseInterval(NOTE n, int interval_kind, int count );
int note_LowerInterval(NOTE n, int interval_kind, int count);
int note_ExportToString(NOTE n, char *buf, int buflen);
int note_ExportToAbcString(NOTE n, char *buf, int buflen); 
const char *note_GetStaticAbcString(NOTE n); 
int note_Print(NOTE n);

#endif /* __NOTE_H__ */

